//FileLoadFuncs:读取文件相关函数


var g_LevelCount = new Int32Array(256);     //各个灰度值数目
var g_LevelMax = 0;
var g_HBWidth = 0;

function readVolumeRaw() {
    var StartLoadTime = getPresentSecond();     //开始读取文件的时间

    gl=getGLFromDoc();

    var txts = document.getElementById('VolumeRawFile');
    txt = txts.files[0];

    var RawFileWidth = getNumFromInput('RawFileWidth');
    var RawFileHeight = getNumFromInput('RawFileHeight');
    var RawFileDepth = getNumFromInput('RawFileDepth');
    var VolumeTexWidth = getNumFromInput('VolumeTexWidth');
    var VolumeTexHeight = getNumFromInput('VolumeTexHeight');

    FillVec3Data(g_v3_volSize, RawFileWidth/VolumeTexWidth, RawFileHeight/VolumeTexHeight, RawFileDepth);

    var TexXDivid = Math.floor(VolumeTexWidth/RawFileWidth);

    var reader = new FileReader();

    reader.readAsArrayBuffer(txt);
    reader.onload = function (e) {
        var FileData = new Uint8Array(this.result);

        AddUpLevelCount(FileData);               //统计各灰度值数目
        ui_ModifyHistogram();                    //绘制灰度值直方图

        StartReadTexAsync(FileData);            //重要，从16版本开始变为异步处理文件，一是为了不让程序卡主，二是为了显示进度
    }


    function StartReadTexAsync(RawData)
    {
        var data = new Uint8Array(VolumeTexWidth*VolumeTexHeight*4);    //申请一块存储纹理数据的空间*4是因为有rgba四个通道各占一个8bit

        //初始化下纹理数据
        for(var i=0;i<VolumeTexWidth*VolumeTexHeight;i++)
        {
            data[i*4+0] = 128;
            data[i*4+1] = 128;
            data[i*4+2] = 128;
            data[i*4+3] = 0;
        }

        var layer = 0;  //layer表示第几层
        (function () {
            if(layer<RawFileDepth)
            {
                var row = Math.floor(layer / TexXDivid);    //第几行
                var col = layer % TexXDivid;                 //第几列

                for (var h = 0; h < RawFileHeight; h++)
                    for (var w = 0; w < RawFileWidth; w++)
                    {
                        var index = ((h + row * RawFileHeight) * VolumeTexWidth + (w + col * RawFileWidth)) * 4;      //index表示这个数据应该放置的位置

                        //注意：从16版本开始，要计算xyz方向梯度放在纹理的rgb通道中，这是为了方便之后的光照等效果
                        data[index + 3] = getDataFromRaw(RawData, w, h, layer);                                                             //灰度值
                        data[index + 0] = (getDataFromRaw(RawData, w + 1, h, layer) - getDataFromRaw(RawData, w - 1, h, layer)) / 2 + 128;  //x方向梯度放在r通道上
                        data[index + 1] = (getDataFromRaw(RawData, w, h + 1, layer) - getDataFromRaw(RawData, w, h - 1, layer)) / 2 + 128;  //y方向梯度放在g通道上
                        data[index + 2] = (getDataFromRaw(RawData, w, h, layer + 1) - getDataFromRaw(RawData, w, h, layer - 1)) / 2 + 128;  //z方向梯度放在b通道上
                    }
                layer++;

                //显示处理进度
                document.getElementById("LoadFileProgress").style.width=""+(layer/RawFileDepth*100)+"%";        //

                //开始下一个读取操作
                setTimeout(arguments.callee, 0);
            }
            else
            {
                FinishAsyncLoad(data);      //结束读取文件
            }
        })();

        function FinishAsyncLoad(data) {

            data = CorrectEdge(data);
            //申请一个纹理
            var tex = gl.createTexture();
            gl.bindTexture(gl.TEXTURE_2D, tex);

            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, VolumeTexWidth, VolumeTexHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);//详细的纹理数据
            gl.generateMipmap(gl.TEXTURE_2D);
            gl.bindTexture(gl.TEXTURE_2D, null);
            g_tex_VolumeData = tex;             //把结果赋给体数据纹理

            //显示读取文件耗时
            setInner("LoadFileProgress","读取耗时："+(Math.floor((getPresentSecond()-StartLoadTime)*1000)/1000)+"秒");
        }

        function CorrectEdge(data)      //修正一下边缘（边缘的梯度值信息是错误的）
        {
            for(layer=0;layer<RawFileHeight;layer+=(RawFileHeight-1)) {
                var row = Math.floor(layer / TexXDivid);    //第几行
                var col = layer % TexXDivid;                 //第几列

                for (var h = 0; h < RawFileHeight; h+=(RawFileHeight-1))
                    for (var w = 0; w < RawFileWidth; w+=(RawFileWidth-1)) {
                        var index = ((h + row * RawFileHeight) * VolumeTexWidth + (w + col * RawFileWidth)) * 4;      //index表示这个数据应该放置的位置

                        data[index + 0] = 128;  //x方向梯度放在r通道上
                        data[index + 1] = 128;  //y方向梯度放在g通道上
                        data[index + 2] = 128;  //z方向梯度放在b通道上
                    }
            }
            return data;
        }

    }


    function AddUpLevelCount(RawData)
    {
        g_LevelMax = 0;
        for(var i=0;i<256;i++)
            g_LevelCount[i] = 0;
        var amount = RawFileWidth*RawFileHeight*RawFileDepth;
        for(var i=0;i<amount;i++)
            g_LevelCount[RawData[i]]++;
        for(var i=0;i<256;i++)
        {
            if(g_LevelMax<g_LevelCount[i])
                g_LevelMax = g_LevelCount[i];
        }
    }

    function getDataFromRaw(RawData,x, y, z)    //依照xyz获取体数据的值
    {
        return RawData[z * (RawFileHeight * RawFileWidth) + y * RawFileWidth + x];
    }
}

function DrawHistogram(inner,border,blank,colorType,colorInner,colorBorder,HBHeight)
{
    var canvas = document.getElementById("HistogramCanvas")
    var context = canvas.getContext("2d");

    ModifyHBWidth(inner+border*2+blank);

    canvas.width = g_HBWidth*256;
    var canvasHeight = canvas.height;


    for(var i=0;i<256;i++)
    {
        drawOneRect(i,canvasHeight*(g_LevelCount[i]/g_LevelMax)*(Math.pow(1.1,HBHeight)));
    }


    function drawOneRect(index, height)
    {
        var pos = index*(g_HBWidth)+Math.floor(blank/2);
        context.fillStyle=colorBorder;
        context.fillRect(pos, canvasHeight-height, inner+border*2, height);
        context.fillStyle=colorInner;
        context.fillRect(pos+border, canvasHeight-height+border, inner, height-border);
    }
}

function ModifyHBWidth(value)
{
    g_HBWidth = value;
    ReDrawTFTex();
    ResetTFBtnPos();
    ResetCursor();
}